﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using TopVisionVideoStream;
using VideoStream.Common;

namespace VideoStream.Windows
{
    public partial class Windows_Draw : VideoStream.Windows.WindowsBase
    {
        #region Filds

        private Control target;
        private Point newLocation = Point.Empty;
        private Size newSize = Size.Empty;
        private DrawTools dt;
        private Point drawPoint = Point.Empty;
        private bool sendMark = true;

        #endregion


        #region Property

        public bool SendMark
        {
            get { return sendMark; }
            set { sendMark = value; }
        }

        #endregion

        public Windows_Draw(Control target)
        {
            this.target = target;
            InitializeComponent();
            InitUI();
        }

        public override void InitUI()
        {
            base.InitUI();

            this.ShowInTaskbar = false;
            this.showBorder = false;
            this.BackColor = TransparencyKey;

            //// size scale
            //double roid = (double)TVVS.QosInformation.QosDownResolutionData.Width / (double)TVVS.QosInformation.QosDownResolutionData.Height;
            //newSize.Height = target.Height;
            //newSize.Width = (int)(roid * target.Height);

            if (ApplicationData.markType != 0) MarkOption.GeoType = ApplicationData.markType;
            if (!string.IsNullOrEmpty(ApplicationData.markColor)) MarkOption.ColorType = ApplicationData.markColor;
            if (ApplicationData.markSolid != 0) MarkOption.SolidType = ApplicationData.markSolid;
        }

        protected override void OnLoad(EventArgs e)
        {
            InitEvent();
            UpdateUI();
            CreatCanvas();
            base.OnLoad(e);  
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            dt.ClearVar();
            UnRegisteEvent();
        }

        public override void InitEvent()
        {
            base.InitEvent();
            RegistEvent();
        }


        public override void UpdateUI()
        {
            base.UpdateUI();
            UpdateSize();
            UpdateLocation();
        }

        #region Control Event

        private void Windows_Draw_VisibleChanged(object sender, EventArgs e)
        {
            if (this.Visible)
            {
                if (!this.IsDisposed)
                {
                    UpdateCanvas(100);
                    UpdateSize();
                    UpdateLocation();
                }
            }
        }

        private void Target_VisibleChanged(object sender, EventArgs e)
        {
            if (target != null)
            {
                if (!target.IsDisposed)
                    this.Visible = target.Visible;
            }
        }

        private void Target_LocationChanged(object sender, EventArgs e)
        {
            UpdateLocation();
        }

        private void Target_SizeChanged(object sender, EventArgs e)
        {
            UpdateSize();
        }

        private void Target_Disposed(object sender, EventArgs e)
        {
            Windows_Main.Instance.LocationChanged -= Target_LocationChanged;
            Hide();
            Close();
        }

        private void Target_MouseUp(object sender, MouseEventArgs e)
        {
            if (dt.startDraw)
            {
                dt.startDraw = false;
                dt.EndDraw();
                if (SendMark)
                {
                    drawPoint = target.PointToScreen(PointToClient(e.Location));
                    int width = this.Width;
                    int height = this.Height;
                    int sX = dt.startPointF.X;
                    int sY = dt.startPointF.Y;
                    int eX = drawPoint.X;
                    int eY = drawPoint.Y;
                    int pT = MarkOption.GeoType;
                    string cT = MarkOption.ColorType;
                    int pWidth = MarkOption.SolidType;

                    TVVS.Features_Mark(width, height, sX, sY, eX, eY, pT, cT, pWidth);
                }
            }
        }

        private void Target_MouseMove(object sender, MouseEventArgs e)
        {
            if (dt.startDraw)
            {
                drawPoint = target.PointToScreen(PointToClient(e.Location));
                string t = "Rect";
                switch (MarkOption.GeoType)
                {
                    case 3:
                        t = "Rect";
                        break;
                    case 5:
                        t = "Circle";
                        break;
                    case 10:
                        t = "Line";
                        break;
                    default:
                        break;
                }
                dt.Draw(drawPoint, t);
            }
        }

        private void Target_MouseDown(object sender, MouseEventArgs e)
        {
            dt.startDraw = true;
            drawPoint = target.PointToScreen(PointToClient(e.Location));
            dt.startPointF.X = drawPoint.X;
            dt.startPointF.Y = drawPoint.Y;
            dt.DrawColor = ColorTranslator.FromHtml(MarkOption.ColorType);
            dt.Solid = MarkOption.SolidType;
        }


        private void MarkOption_Click(object sender, EventArgs e)
        {
            ApplicationData.markType = MarkOption.GeoType;
            ApplicationData.markColor = MarkOption.ColorType;
            ApplicationData.markSolid = MarkOption.SolidType;
        }

        private void MarkOption_ClearClick(object sender, EventArgs e)
        {
            Graphics g = this.CreateGraphics();
            g.FillRectangle(new SolidBrush(this.TransparencyKey), 0, 0, target.Width, target.Height);
            g.Dispose();
            CreatCanvas();
            TVVS.Features_ClearMark();
        }

        #endregion


        #region Method

        private void CreatCanvas()
        {
            Bitmap bmp = new Bitmap(this.target.Width, this.target.Height);
            Graphics g = Graphics.FromImage(bmp);
            g.FillRectangle(new SolidBrush(this.TransparencyKey), 0, 0, target.Width, target.Height);
            dt = new DrawTools(this.CreateGraphics(), TransparencyKey, bmp);
            g.Dispose();
            bmp.Dispose();
        }

        public void UpdateLocation()
        {
            newLocation = target.PointToScreen(Point.Empty);
            newLocation.X += (target.Width - this.Width) / 2;
            this.Location = newLocation;
        }

        public void UpdateSize()
        {
            // size scale
            double roid = (double)TVVS.QosInformation.QosDownResolutionData.Width / (double)TVVS.QosInformation.QosDownResolutionData.Height;
            newSize.Height = target.Height;
            newSize.Width = (int)(roid * target.Height);
            this.Size = newSize;
        }

        private void RegistEvent()
        {
            if (target != null)
            {
                if (!target.IsDisposed)
                {
                    target.MouseDown += Target_MouseDown;
                    target.MouseMove += Target_MouseMove;
                    target.MouseUp += Target_MouseUp;
                    target.SizeChanged += Target_SizeChanged;
                    target.LocationChanged += Target_LocationChanged;
                    Windows_Main.Instance.WinDisplay.VisibleChanged += Target_VisibleChanged;
                    target.Disposed += Target_Disposed;
                }
            }
            if (Windows_Main.Instance != null)
            {
                if (!Windows_Main.Instance.IsDisposed)
                {
                    Windows_Main.Instance.LocationChanged += Target_LocationChanged;
                }
            }

            MarkOption.Click += MarkOption_Click;
            MarkOption.ClearClick += MarkOption_ClearClick;

            this.VisibleChanged += Windows_Draw_VisibleChanged;
        }

        private void UnRegisteEvent()
        {
            if (target != null)
            {
                if (!target.IsDisposed)
                {
                    target.MouseDown -= Target_MouseDown;
                    target.MouseMove -= Target_MouseMove;
                    target.MouseUp -= Target_MouseUp;
                    target.SizeChanged -= Target_SizeChanged;
                    target.LocationChanged -= Target_LocationChanged;
                    Windows_Main.Instance.WinDisplay.VisibleChanged -= Target_VisibleChanged;
                    target.Disposed -= Target_Disposed;
                }
            }
            if (Windows_Main.Instance != null)
            {
                if (!Windows_Main.Instance.IsDisposed)
                {
                    Windows_Main.Instance.LocationChanged -= Target_LocationChanged;
                }
            }

            MarkOption.Click -= MarkOption_Click;
            MarkOption.ClearClick -= MarkOption_ClearClick;
        }

        private async void UpdateCanvas(int delay)
        {
            await Task.Delay(delay);
            Graphics g = this.CreateGraphics();
            g.DrawImage(dt.CurImage, 0, 0);
        }

        public void ClearMark()
        {
            TVVS.Features_ClearMark();
        }
        #endregion
    }
}
